#include "EventTrans.h"
#include <iostream>

using namespace std;

EventSender::EventSender()
{
    /*
     *initialize the socket that is used to send message
     */
    sock_fd_out = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd_out < 1){
        perror("error: sock_fd_out create failed.\n");
    }
    //socket options
    int so_broadcast = 1;
	setsockopt(sock_fd_out,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));
}

EventReceiver::EventReceiver()
{
    /*
     * initialize the socket that is used to receive message
     */
    //initialize address info

    struct sockaddr_in recv_addr;
    recv_addr.sin_family = AF_INET;
    recv_addr.sin_port = htons(PORT_UDP_IN);
    recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //create socket and bind
    sock_fd_in = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd_in<0){
        perror("error: receive socket create error.\n");
    }
    if(bind(sock_fd_in,(struct sockaddr*)&recv_addr,sizeof(recv_addr))<0)
    {
        cerr<<"error : bind sock_fd_in error."<<endl;
    }
}

EventSender::~EventSender()
{
    close(sock_fd_out);
}

EventReceiver::~EventReceiver()
{
    close(sock_fd_in);
}

void EventSender::send_msg(AbstractEvent& event){

    // initialize the address message
    int port = PORT_UDP_IN;
    char* ip_addr = event.dest_ip;
    struct sockaddr_in dest; // address to be sended
    dest.sin_family = AF_INET;
    dest.sin_port = htons(port);
    dest.sin_addr.s_addr = inet_addr(ip_addr);
	// send message
	if(sendto(sock_fd_out,&event,size_event(event),0,(struct sockaddr*)&dest,sizeof(dest))<0)
	{
	    cerr<<"error: send by sock_fd_out! "<<endl;
	}
	delete (char*)&event;
}

AbstractEvent* EventReceiver::recv_msg(){
    int real_size;
    char* event=new char[MAX_EVENT_SIZE];
	real_size = recvfrom(sock_fd_in, event, MAX_EVENT_SIZE, 0, NULL, NULL);
	if(real_size > 0){
	    return (AbstractEvent*)event;
	}else{
	    return NULL;
	}
}
